<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jquery cookbook</title>
    <style>
        .context{
            display: -webkit-flex;
            display: flex;
            -webkit-flex-wrap: wrap;
            flex-wrap: wrap;
            width: 100%;
            height: 100%;
        }
        .box{
            display: -webkit-box;
            display: -webkit-flex;
            display: flex;
            -webkit-box-pack: center;
            -webkit-justify-content: center;
            justify-content: center;
            -webkit-box-align: center;
            -webkit-align-items: center;
            align-items: center;
            box-sizing: border-box;
            border: 1px solid #666;
            width: 100px;
            height: 100px;
            background: wheat;
            color: #666;
            /*border-collapse: separate;*/
        }
        *::after{
            content: attr(class);
        }

        #jquery1 button{
            display: block;
        }

        #target{
            border: 1px solid;
        }

        #created{
            border: 1px dashed blue;
        }
        .context a{
            display: block;
        }
        #next{
            position: fixed;
            right: 5%;
            bottom: 30%;
            display: block;
            border-radius: 10px;
            border: 1px solid #eee;
            width: 5em;
            height: 2em;

        }
        div{
            margin: 1em 0;
        }
        p{
            white-space: pre;
        }
        span{
            font-size: 14px;
        }
        strong{
            color: red;
        }
    </style>
</head>
<body>
    <button id="next">next</button>

    <article id="jquery1">
        <h2>jQuery basics</h2>
        <div class="context">
            <div class="null box"></div>
            <div class="filter box"></div>
            <div>
                <button class="attr"></button>
                <button class="removeAttr"></button>
                <a>类似的还有addClass,hasClass,removeClass,toggleClass</a>
            </div>
        </div>
        <div class="out-context box filter"></div>

        <div class="box andSelf">
            <p class="p"></p>
        </div>

        <div id="target" class="target">
            <p id="target-p" class="target-p">
        </div>
        </p>
        <button class="appendTo"></button>
        <button class="append"></button>
        <button class="prepend"></button>
        <button class="prependTo"></button>
        <button class="after"></button>
        <button class="before"></button>
        <button class="insertAfter"></button>
        <button class="insertBefore"></button>
        <button class="wrap"></button>
        <button class="wrapAll"></button>
        <button class="wrapInner"></button>
        <button class="remove"></button>
        <button class="remove-and-return"></button>
        <button class="clone"></button>
        <pre>
            原生DOM里就有removeChild 与 remove 方法
            但jquery的remove有不同的地方:
            • WhiletheelementsselectedareremovedfromtheDOMusingremove(),
              theyhave not been removed from the jQuery wrapper set.

              That means in theory you could continue operating on them and even add them back into the DOM if desired.
            • This method will not only remove the elements from the DOM,
              but it will also remove all event handlers and internally cached data that the elements removed might have contained.
        </pre>
        <pre>
            未写出来的api
            jQuery('li:eq(1)').next() //selects the third li
            jQuery('li:eq(1)').prev() //selects the first li
            jQuery('li:eq(1)').parent() //selects the ul
            jQuery('li:eq(1)').parent().children() //selects all lis
            jQuery('li:eq(1)').nextAll() //selects all the lis after the second li
            jQuery('li:eq(1)').prevAll() //selects all the lis before the second li
        </pre>
        <p>
            后面还有
            html
            text
            val
            等api,就不一一列举了
        </p>
    </article>
    <article id="jquery2">
        <h2>第二章 选择元素</h2>
        <section>
        <h3>select elements direct child elements only 子元素:</h3>
        <pre>
            // Getting all direct children of all anchor elements can be achieved in three ways:
            var anchors = jQuery('a');

            // #1 anchors.children();

            //#2 jQuery('> *', anchors);

            // #3 anchors.find('> *');

            In this situation, the first method is the fastest.
            you can also pass a selector expression to the children() method to filter the results:
            jQuery('#content').children('p');
        </pre>
        </section>
        <section>
            <h3>select specific siblings 兄弟元素:</h3>
            <ul>
                <li class="first"></li>
                <li class="selected-li"></li>
                <li class="third"></li>
                <li class="forth"></li>
                <li class="fifth"></li>
            </ul>
            <span>请点击.selected-li, 观察console</span>
            <pre>
                jQuery('h1 + h2'); // Selects ALL H2 elements that are adjacent siblings of H1 elements

                jQuery('h1').siblings('h2,h3,p'); // Selects all H2, H3, and P elements that are siblings of H1 elements.

                jQuery('li.selected').nextAll('li');
            </pre>
        </section>
        <section>
            <h3>select elements by index order 根据次序选择:</h3>
            <pre>
                :first
                    Matches the first selected element
                :last
                    Matches the last selected element
                :even
                    Matches even elements (zero-indexed)
                :odd
                    Matches odd elements (zero-indexed)
                :eq(n)
                    Matches a single element by its index (n)
                :lt(n)
                    Matches all elements with an index below n
                :gt(n)
                    Matches all elements with an index above n
            </pre>
            <span>选择第一个元素有三种方法:</span>
            <pre>
                jQuery('ol li:first');
                jQuery('ol li:eq(0)');
                jQuery('ol li:lt(1)');
            </pre>
            <span>也可以在filter里传这些表达式</span>
            <pre>
                jQuery('ul li').filter(':first');
            </pre>
        </section>
        <section>
            <h3>文本是否包含</h3>
            <pre>
                 Select all spans with 'Bob' in:
                 jQuery('span:contains("Bob")');
            </pre>
            <span>如果不满意,可以自定义filter规则:</span>
            <pre>
                jQuery('p').filter(function(){
                    return /(^|\s)(apple|orange|lemon)(\s|$)/.test(jQuery(this).text());
                });
            </pre>
            <strong>另:filter使用技巧,使用!!来把值转换成Boolean型</strong>
            <pre>
               jQuery('*').filter(function(){
                   return !!jQuery(this).css('backgroundImage');
               });
            </pre>
        </section>
        <section>
            <h3>select by what they don't match</h3>
            <pre>
                jQuery('div:not(#content)'); // Select all DIV elements except #content

                可以对一个jq wrapper set使用not:
                var $anchors = jQuery('a');
                $anchors.click(function(){
                    $anchors.not(this).addClass('not-clicked');
                });
            </pre>
        </section>
        <section>
            <h3>根据可见性</h3>
            <pre>
                log($('body>*:hidden'));
                display:none的会在里面,脚本也会在里面.所以实战的时候注意一下
            </pre>
        </section>
        <section>
            <h3>根据属性</h3>
            <pre>
                [attr]
                    选择有属性不为空的元素 #('img[src]');
                [attr=val]
                    Matches elements that have the specified attribute with a certain value
                [attr!=val]
                    Matches elements that don’t have the specified attribute or value
                [attr^=val]
                    Matches elements with the specified attribute and that start with a certain value
                [attr$=val]
                    Matches elements that have the specified attribute and that end with a certain value
                [attr~=val]
                    Matches elements that contain the specified value with spaces,
                    on either side (i.e., car matches car but not cart)
            </pre>
        </section>
        <section>
            <h3>select by type:</h3>
            <pre>
                :text
                :password
                :radio
                :checkbox
                :submit
                :image
                :reset
                :button
                :file
                :hidden
            </pre>
        </section>
        <section>
            <h3>根据上下文(选择器中,第二个参数):</h3>
            <pre>
                jQuery('form').bind('submit', function(){
                    var allInputs = jQuery('input', this);
                    // Now you would do something with 'allInputs'
                });
            </pre>
        </section>
        <section>
            <h3>最后的高级主题:自定义filter,使用extends函数,这个还不会呀</h3>
        </section>
    </article>
    <article id="jquery3">
        <h2>beyond the basics</h2>
        <p>
            Convert a Selected jQuery Object into a Raw DOM Object
        </p>
    </article>

    <script src="../public/js/jquery.js"></script>
    <script>
        var log = function(msg){
            console.log(msg);
        };
        $(function(){
            //只显示一个article
            var $articles = $('article').each(function(i,article){
                if(i == 2) return;
                $(this).hide();
            });

            $('#next').click(function(){
                for(var i = 0; i < $articles.length; i++){
                    var article = $articles[i];
                    if(article.style.display != 'none'){
                        article.style.display = 'none';
                        //是否最后一个元素
                        if(i != $articles.length - 1)
                            $articles.eq(i+1).show();
                        else
                            $articles.eq(0).show();
                        break;
                    }
                }
            });

            var $query = $('div');
            log($query);
            log($query[0]);//undefined,因为返回的是数组
            //就算没有div元素,也会有wrapper set,下面的语句也不会报错
//            $query.text('div');

            log('2');
            $query = $('div','.context').filter('.filter');
//            $query = $('div').filter('.filter');
            log('filter length in context: ' + $query.length);

            $query = $('div').filter(function(index){
               return 'hehe';
//                return undefined;
//                return NaN;
//                return 0;
//                return '';
//                return false;
            });
            //只要return不为假值:不一定是false,还包括undefined,NaN,0,'',元素留下
            log('div after filter(function(index){hehe}): ' + $query.length);

            $query = $('.andSelf').find('p').andSelf();
//            $query = $('.andSelf').find('p');
            log('3 andSelf, add prev set into current set');
            log($query);

            log('4 end(), return prev set');
            log($query.end());

            jQuery('<p><a>this link created by jQuery</a></p>')
                    .find('a').attr('href','http://www.jquery.com')
                    .end().appendTo($('#jquery1'));

            //manipulation function
            var btns = $('#jquery1').find('button');
            //jquery 的集合要用each啊!!! map 是原生的数组函数
//            log(btns);
            btns.each(function(i,btn){
                //这样就是普通的dom元素了
//                log(btn)
                btn.onclick = function(){
//                    log(btn.getAttribute('class'));
//                    var btn_method = btn.getAttribute('class');
//                    $(btn).btn_method(div);
                };
            })

            //为不同的btn绑定不同的click事件
            //注意,这里也是使用引用的,故一个div,只能在一个地方出现,
            //也即,把div放在一个地方后,又放在另一个地方,则div会在前一个地方消失,出现在后一个地方
//            var div = $('<div>div created by jquery</div>');
            var div_str = '<div class="created">div created by jquery,删除只是不在dom树里,但还在内存里,随时可以回来</div>'
            for(var i = 0; i < btns.length; i++){
                var btn = btns[i];
                if(i == 0)
                    btn.onclick = function(){
                        $(div_str).appendTo($('#target'));
                    }
                if(i == 1)
                    btn.onclick = function(){
                        //非块级元素append,会出现什么结果?
                        $(btn).append($(div_str));
                        $('#target').append($(div_str));
                    }
                if(i == 2)
                    btn.onclick = function(){
                        $('#target').prepend($(div_str));
                    }
                if(i == 3)
                    btn.onclick = function(){
                        $(div_str).prependTo($('#target'));
                    }
                if(i == 4)
                    btn.onclick = function(){
                        $('#target').after(div_str);
                    }
                if(i == 5)
                    btn.onclick = function(){
                        $('#target').before(div_str);
                    }
                if(i == 6)
                    btn.onclick = function(){
                        $(div_str).insertAfter($('#target'));
                    }
                if(i == 7)
                    btn.onclick = function(){
                        $(div_str).insertBefore($('#target'));
                    }
                if(i == 8)
                    btn.onclick = function(){
                        //这个是被新元素包围了
                        $('#target').wrap(div_str);
                    }
                if(i == 9)
                    btn.onclick = function(){
                        $('#target').wrapAll(div_str);
                    }
                if(i == 10)
                    btn.onclick = function(){
                        //这个才是包围新元素
                        $('#target').wrapInner(div_str);
                    }
            }

            $('.remove').on('click',function(){
                var $divs = $('.created');
                if($divs.length){
                    $divs.eq(0).remove();
                }
                else{
                    $('button').eq(0).remove();
                }
            });

            (function($){
                var $div = $(div_str),
                    $btn = $('.remove-and-return'),
                    click = false;

                $btn.before($div);
                $btn.on('click',function(){
                    if(!click){
                        click = true;
                        $div.remove();
                    }
                    else{
                        click = false;
                        $btn.before($div);
                    }
                });
            })($);

            $('.clone').click(function(){
                //clone event
                //多个id, 只会选择第一个
                $('#jquery1').clone(true).appendTo(document.body);
            });

            $('.attr').click(function(){
                $(this).parent().find('a').attr('href','www.jquery.com');
            });

            $('.removeAttr').click(function(){
                $(this).parent().find('a').removeAttr('href');
            });

            //two
            $('.selected-li').click(function(){
                log('use + '); log($('.selected-li + li'));
                log('use siblings() '); log($(this).siblings());
                log('use nextAll() '); log($(this).nextAll());

            });

        });
    </script>
</body>
</html>